package other.edan.order;

import com.rkhd.platform.sdk.api.annotations.RequestMethod;
import com.rkhd.platform.sdk.api.annotations.RestApi;
import com.rkhd.platform.sdk.api.annotations.RestMapping;
import com.rkhd.platform.sdk.api.annotations.RestQueryParam;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEvent;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventRequest;
import com.rkhd.platform.sdk.creekflow.approvalevent.ApprovalEventResponse;
import com.rkhd.platform.sdk.data.model.*;
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.exception.XsyHttpException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.model.BatchOperateResult;
import com.rkhd.platform.sdk.model.OperateResult;
import com.rkhd.platform.sdk.model.XObject;
import org.apache.commons.lang.StringUtils;
import other.edan.order.utils.HCDateUtils;
import other.edan.order.utils.HCXObjectService;
import other.edan.order.utils.Result;
import other.edan.order.utils.TfReturnMsgTools;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**功能描述：内部订单审批通过后，生成正式销售合同（硬件和软件）
 * @ClassName: InternalOrderAfterApproval
 * @Description:
 * @author 范伟绵
 * @date 2024年12月23日
 */

@RestApi(baseUrl = "/xsy/edan")
public class InternalOrderAfterApproval implements ApprovalEvent {
	private final static Logger LOGGER = LoggerFactory.getLogger();
	private final static String LOG_MSG_EX="内部订单审批通过后，生成正式销售合同（硬件和软件）:";
	private final static Integer hardType=1;  	//硬件合同
	private final static Integer softType=2; 	//软件合同
	private final Map<String,Double> hardSoftRatioMap =new HashMap<>();	//硬件对应的“软件料号”和比例
	private final Map<String,List<OrderProduct>> softOrderProductMap =new HashMap<>();	//软件对应的父产品（组合包）

	public ApprovalEventResponse execute(ApprovalEventRequest request) throws ScriptBusinessException {
		Long id = request.getDataId();
		request.getEntityApiKey();
		LOGGER.info(LOG_MSG_EX + "开始，数据ID:"+id);
		
		ApprovalEventResponse response = new ApprovalEventResponse();
		try {
			response= handler(id);
		} catch (Exception e) {
			response= TfReturnMsgTools.getApprResponse(false, LOG_MSG_EX + "失败.");
			LOGGER.error(LOG_MSG_EX +"发生异常"+e.getMessage());
			return response;
		}
		LOGGER.info(LOG_MSG_EX + "结束");
		return response;
	}
	
	@RestMapping(value = "/generateSalesContract", method = RequestMethod.POST)
	public String generateSalesContract(@RestQueryParam(name="id") String id)  {
		LOGGER.info(LOG_MSG_EX+"执行了按钮事件 id = " + id);
		try{
			ApprovalEventResponse response= handler(Long.valueOf(id));
			return TfReturnMsgTools.getJsonResult(response.getSuccess(),response.getMsg());
		}catch (Exception e){
			LOGGER.error("生成【正式销售合同】发生异常:"+e.getMessage());
			return TfReturnMsgTools.getExceptionResult("生成【正式销售合同】失败，请联系管理员！");
		}
	}

    public static void main(String[] args) throws Exception {
        HCXObjectService.isLocal = true;
        InternalOrderAfterApproval api = new InternalOrderAfterApproval();
        api.handler(3709230268963473L);


        //String contractCode = api.getContractCode();
        //System.out.println("contractCode = " + contractCode);
    }
	
	/*功能描述：生成正式销售合同
	 * id：单据ID
	 */
	@SuppressWarnings("unchecked")
	public ApprovalEventResponse handler(Long internalOrderId) throws ApiEntityServiceException, IOException, XsyHttpException {
		String returnMsgString= "获取【内部订单】信息失败";
		
		//获取【内部订单】信息
		Order order=new Order();
		order.setId(internalOrderId);
		order= HCXObjectService.get(order);
		if(null==order) {
			LOGGER.error(returnMsgString);
			return TfReturnMsgTools.getApprResponse(false, returnMsgString);
		}
		LOGGER.info("【内部订单】信息:"+order.toString());

		//获取【订单明细】信息
		String sqlString="Select id,name,productId,parentLine,quantity,unitPrice,unitPriceExcludingTax__c,totalAmountExcludingTax__c," +
				" ruanJian__c,FNote__c,taxRate__c,FItemID__c,productRegistrationModel__c,productRegistrationName__c" +
				" from orderProduct where orderId = " + internalOrderId;
		List<OrderProduct> orderProductList=HCXObjectService.queryAll(sqlString);
		if(orderProductList.isEmpty()) {
			//没有明细
			LOGGER.info("没有【订单明细】信息");
			return TfReturnMsgTools.getApprResponse(false, "没有【订单明细】.");
		}
		LOGGER.info("【订单明细】信息:"+orderProductList.toString());

		//获取订单购货单位信息，带入到正式销售合同中
		Account account=new Account();
		account.setId(order.getAccountId());
		account=HCXObjectService.get(account);

		//生成硬件和软件正式销售合同
        Result result = generateContractAndDetail(account, order, orderProductList);
        boolean isSuc = result.getCode() == 200;

        LOGGER.info("handler 结束,");
		return TfReturnMsgTools.getApprResponse(isSuc, isSuc ? "下推【正式销售合同】成功" : String.format("下推【正式销售合同】异常 ( %s )", result.getMsg()));
	}

	//构建合同主表
	private Contract getContract(String title,Account account,Order order,Integer type, String version){
		Contract contract=new Contract();
		contract.setEntityType(11010001500001L);    			//国内营销正式销售合同
		contract.setTitle(title);					//合同编号

        contract.setDelivery__c(2); // 交付方式（默认: 卖方托运、送货）
		contract.setOpportunityId(order.getOpportunityId());	//项目名称
		contract.setVersionNo__c(version);							//版本号
		contract.setAccountId(order.getAccountId());			//购货单位
		contract.setPaymentMethod__c(order.getFPayStyle__c());	//付款方式
		contract.setConsignee__c(order.getReceiverName());		//收货人
		contract.setDeliveryDate__c(null);						//发货日期：TODO
		contract.setMainframeWarrantyPeriod__c(null);			//主机保修期（月）：TODO
		contract.setPartsWarrantyPeriod__c(null);				//配件保修期（月）：TODO
		contract.setTicket__c(order.getFHeadSelfS0176__c());	//票种
		contract.setAmount(0.0);								//总金额
		contract.setHeTongType__c(type);						//合同类型

		//设置客户相关信息
		contract.setBankOfDeposit__c(account.getFBank__c());	//购货单位开户行
		contract.setAccountNumber__c(account.getFAccount__c());	//购货单位账号
		contract.setAddress__c(account.getAddress());			//购货单位地址
		contract.setTelephone__c(account.getFPhone__c());		//购货单位电话

		return contract;
	}

	//合同编号:202400001,202400002
	private String getContractCode(){
		String sql="select title from contract where entityType = 11010001500001 and title like '20%' order by title DESC";
		Contract contract=HCXObjectService.queryOne(sql);
		if(contract==null) {
			return HCDateUtils.getYear(new Date())+"00001,"+HCDateUtils.getYear(new Date())+"00002";
		}

		int number1=Integer.parseInt(contract.getTitle().substring(4))+1;
		int number2=number1+1;
		String formattedNumber1 = String.format("%05d", number1);
		String formattedNumber2 = String.format("%05d", number2);
		return HCDateUtils.getYear(new Date())+formattedNumber1+","+HCDateUtils.getYear(new Date())+formattedNumber2;
	}

	//生成硬件和软件销售合同（含明细）
	private Result generateContractAndDetail(Account account, Order order, List<OrderProduct> orderProductList) {
        // 先判断是否已经存在合同编号，存在则只需要递增版本号
        String nowContractCodes = order.getFHeadSelfS0153__c();
        String[] splitCode = new String[2];
        String versionStr = "V1";
        if (StringUtils.isNotBlank(nowContractCodes)) {
           splitCode = nowContractCodes.split(";");
           // 获取最新的版本号
            versionStr = getContractVersion(splitCode[0]);
        } else {
            //获取合同编号:DM202400001,DM202400002，硬件合同取前半部分，软件合同取后半部分
            String newContractCodes = getContractCode();
            splitCode = newContractCodes.split(",");
        }
		Contract hardwareContract = getContract(splitCode[0], account,order,hardType, versionStr);		//硬件合同
		Contract softwareContract = getContract(splitCode[1], account,order,softType, versionStr);		//软件合同


		boolean hasHardware=false;			//判断是否有硬件产品
		boolean hasSoftware=false;			//判断是否有软件产品

		List<OrderProduct> hardwareOrderProductList=new ArrayList<>();			//硬件明细
		List<OrderProduct> softwareOrderProductList=new ArrayList<>();			//软件明细
		for(OrderProduct orderProduct:orderProductList) {
			if(null!=orderProduct.getRuanJian__c() && 1==orderProduct.getRuanJian__c()){
				//软件产品
				hasSoftware=true;
				softwareOrderProductList.add(orderProduct);
				continue;
			}

			hasHardware=true;
			hardwareOrderProductList.add(orderProduct);
		}

		//新增硬件销售合同
		Long newHardwareContractId=null;
		if(hasHardware) {
			LOGGER.info("硬件合同信息:"+hardwareContract.toString());
			OperateResult insert = HCXObjectService.insert(hardwareContract);
			if(!insert.getSuccess()){
				LOGGER.info("新增硬件销售合同失败："+insert.getErrorMessage());
				return Result.error("新增硬件销售合同失败："+insert.getErrorMessage());
			}
			newHardwareContractId=insert.getDataId();
		}

		//新增软件销售合同
		Long newSoftwareContractId=null;
		if(hasSoftware) {
			LOGGER.info("软件合同信息:"+softwareContract.toString());
			OperateResult insert = HCXObjectService.insert(softwareContract);
			if(!insert.getSuccess()){
                LOGGER.info("新增软件销售合同："+insert.getErrorMessage());
                return Result.error("新增软件销售合同："+insert.getErrorMessage());
			}
			newSoftwareContractId=insert.getDataId();
		}

		//获取软件映射表信息，用于计算软硬件价格
		String sql="select id,name,productSeries__c,hardwareRatio__c,softwareRatio__c,softwarePartNo__c,materialCode__c," +
				"productRegistrationName__c,productRegistrationModel__c from softwareMappingTable__c";
		List<SoftwareMappingTable__c> softwareMappingTableList=HCXObjectService.queryAll(sql);
		LOGGER.info("软件映射数量："+softwareMappingTableList.size());


		//构建硬件销售合同明细
		List<ContractDetails__c> contractDetailsList=new ArrayList<>();
		for(OrderProduct orderProduct:hardwareOrderProductList) {
			ContractDetails__c insertDetail=getContractDetails__c(newHardwareContractId,orderProduct,softwareMappingTableList,orderProductList,hardType);
			if(null==insertDetail) {
				continue;
			}
			contractDetailsList.add(insertDetail);
		}

		//构建软件销售合同明细
		for(OrderProduct orderProduct:softwareOrderProductList) {
			ContractDetails__c insertDetail=getContractDetails__c(newSoftwareContractId,orderProduct,softwareMappingTableList,orderProductList,softType);
			if(null==insertDetail) {
				continue;
			}
			contractDetailsList.add(insertDetail);
		}
		//TEST
		/*for(ContractDetails__c contractDetails:contractDetailsList) {
			HCXObjectService.insert(contractDetails);
		}*/
		//END TEST

		boolean result = true;
        String errMsg = "";
		if(!contractDetailsList.isEmpty()) {
			LOGGER.info("合同明细数量:"+contractDetailsList.size());
			LOGGER.info("合同明细数据："+contractDetailsList.toString());
			BatchOperateResult batchOperateResult = HCXObjectService.insertBatch(contractDetailsList);
            if (batchOperateResult != null) {
                LOGGER.info("批量插入结果:"+ batchOperateResult.getErrorMessage());
                result = batchOperateResult.getSuccess();
                errMsg = batchOperateResult.getErrorMessage();
            }
		}

        // 反写 正式合同编号
        String codes = hardwareContract.getTitle() + ";" + softwareContract.getTitle();
        Order upOrder = new Order();
        upOrder.setId(order.getId());
        upOrder.setFHeadSelfS0153__c(codes);
        HCXObjectService.update(upOrder);

        LOGGER.info(result ? "生成【合同明细】成功" : "生成【合同明细】失败: " + errMsg);
        return result ? Result.success() : Result.error("生成【合同明细】失败："+ errMsg);
	}

	//构建合同明细
	private ContractDetails__c getContractDetails__c(Long newContractId,OrderProduct orderProduct,List<SoftwareMappingTable__c> softwareMappingTableList,List<OrderProduct> orderProductList,Integer type){
		//物料代码以“P”或“p”开头的未虚拟料号，无需带入到正式销售合同中
		if(orderProduct.getFItemID__c().startsWith("P") || orderProduct.getFItemID__c().startsWith("p")){
			//虚拟产品
			LOGGER.info("虚拟产品无需带入到合同中，物料代码："+orderProduct.getFItemID__c());
			return null;
		}

		ContractDetails__c contractDetails=new ContractDetails__c();
		contractDetails.setEntityType(3520923017058908L);
		contractDetails.setContract__c(newContractId);							//合同
		contractDetails.setItem__c(orderProduct.getId());						//项目
		contractDetails.setProductId__c(orderProduct.getProductId()); 			//产品名称
		contractDetails.setQuantity__c(orderProduct.getQuantity());				//数量
        contractDetails.setHostWarranty__c(orderProduct.getFEntrySelfS0173__c()); // 主机保修期
        contractDetails.setPartsWarranty__c(orderProduct.getFEntrySelfS0174__c()); // 配件保修期

		// 获取“含税单价”
		Double price = orderProduct.getUnitPrice();
		if(hardType.equals(type)){
			// 硬件单价
			price = getHardwarePrice(orderProduct,softwareMappingTableList,orderProductList);
		}else{
			// 软件单价 (会存在订单里面有相同产品问题)
			Double ratio = hardSoftRatioMap.get(orderProduct.getFItemID__c());
            List<OrderProduct> mapOrderProductList = softOrderProductMap.get(orderProduct.getFItemID__c());
            OrderProduct fatherOrderProduct = null;
            if (mapOrderProductList != null) {
                if (mapOrderProductList.size() == 1) {
                    fatherOrderProduct = mapOrderProductList.get(0);
                } else {
                    fatherOrderProduct = mapOrderProductList.stream().filter(v -> !Objects.equals(v.getAttribute("isUser"), 1)).findFirst().get();
                    fatherOrderProduct.setAttribute("isUser", 1);
                }
            }
			if(null!=ratio && null!=fatherOrderProduct){
				//(组合产品的实际含税单价*软件比例*100）
				price = BigDecimal.valueOf(fatherOrderProduct.getUnitPrice()).multiply(BigDecimal.valueOf(ratio)).multiply(new BigDecimal(100)).doubleValue();
			}
		}
		contractDetails.setTaxUnitPrice__c(price);		//含税单价（元）

		contractDetails.setProductName__c(orderProduct.getProductConfig__c());	//产品名称（含规格，型号）
		contractDetails.setGuiGe__c(orderProduct.getSpecifications__c());		//规格型号
		contractDetails.setRemark__c(orderProduct.getFNote__c());				//备注
		contractDetails.setTax__c(orderProduct.getTaxRate__c());				//税率（%）
		return contractDetails;
	}

	//获取硬件价格;根据“产品注册名称和产品注册型号”查找
	private Double getHardwarePrice(OrderProduct orderProduct, List<SoftwareMappingTable__c> softwareMappingTableList, List<OrderProduct> orderProductList) {
		//订单明细信息，用于作为参数从“软件映射表”中获取信息
		Double price = orderProduct.getUnitPrice();
		String productRegistrationName = (null == orderProduct.getProductRegistrationName__c()) ? "" : orderProduct.getProductRegistrationName__c().trim();                //产品注册名称
		String productRetRegistrationModel = (null == orderProduct.getProductRegistrationModel__c()) ? "" : orderProduct.getProductRegistrationModel__c().trim();        	//产品注册型号
		String productCode=(null==orderProduct.getFItemID__c())?"":orderProduct.getFItemID__c().trim();																		//产品代码（物料代码）

		//从“软件映射表”中查找符合条件的数据
		List<SoftwareMappingTable__c> resultMappingTable = new ArrayList<>();
		for (SoftwareMappingTable__c softwareMappingTable : softwareMappingTableList) {
			String mappingRegistrationName = softwareMappingTable.getProductRegistrationName__c().trim();
			String mappingtRegistrationModel = softwareMappingTable.getProductRegistrationModel__c().trim();
			if (productRegistrationName.equals(mappingRegistrationName) && productRetRegistrationModel.equals(mappingtRegistrationModel)) {
				resultMappingTable.add(softwareMappingTable);
			}
		}

		//在映射表中没找到
		if (resultMappingTable.isEmpty()) {
			LOGGER.info("在映射表中没找到，返回原订单明细的价格");
			return price;
		}

		SoftwareMappingTable__c resultTable = resultMappingTable.get(0);

		// 找对应的父产品（组合包），用于作为价格取值来源
        // 如果当前有价格则无需向上查找
		OrderProduct fatherOrderProduct = null;
        if (orderProduct.getUnitPrice() > 0) {
            fatherOrderProduct = orderProduct;
        } else {
            fatherOrderProduct = orderProductList.stream().filter(v -> Objects.equals(v.getId(), orderProduct.getParentLine())).findFirst().orElse(null);
        }

		if(null==fatherOrderProduct) {
			LOGGER.info("没找到对应的父产品（组合包）");
			return price;
		}

		//找到多个，还需要根据物料代码再找一次
		if (resultMappingTable.size() > 1) {
			for (SoftwareMappingTable__c softwareMappingTable : resultMappingTable) {
				String mappingRegistrationName = softwareMappingTable.getProductRegistrationName__c().trim();
				String mappingtRegistrationModel = softwareMappingTable.getProductRegistrationModel__c().trim();
				String mappingProductCode=(null==softwareMappingTable.getMaterialCode__c())?"":softwareMappingTable.getMaterialCode__c().trim();

				if (productRegistrationName.equals(mappingRegistrationName) && productRetRegistrationModel.equals(mappingtRegistrationModel) && mappingProductCode.equals(productCode)) {
					resultTable=softwareMappingTable;
					break;
				}
			}
		}

		//把找到的数据存起来，用在软件价格取值来源
		hardSoftRatioMap.put(resultTable.getSoftwarePartNo__c(),resultTable.getSoftwareRatio__c());
        List<OrderProduct> mapSaveList = new ArrayList<>();
        mapSaveList.add(fatherOrderProduct);
        if (softOrderProductMap.containsKey(resultTable.getSoftwarePartNo__c())) {
            mapSaveList.addAll(softOrderProductMap.get(resultTable.getSoftwarePartNo__c()));
        }
		softOrderProductMap.put(resultTable.getSoftwarePartNo__c(), mapSaveList);

		//根据比例算价格(组合产品的实际含税单价*硬件比例*100）
		price= BigDecimal.valueOf(fatherOrderProduct.getUnitPrice()).multiply(BigDecimal.valueOf(resultTable.getHardwareRatio__c())).multiply(new BigDecimal(100)).doubleValue();
		return price;
	}

    /**
     * 根据合同号获取最新版本
     * @param contractCode
     * @return
     */
    public String getContractVersion(String contractCode) {
        String versionStr = "V1";
        String sql = String.format("select id,versionNo__c from contract where title = '%s' ", contractCode);
        XObject xObject = HCXObjectService.queryOne(sql);
        String versionNo = xObject.getAttribute("versionNo__c");
        if (StringUtils.isNotBlank(versionNo)) {
            versionStr = "V" + (Integer.valueOf(versionNo.substring(1)) + 1);
        }
        return versionStr;
    }



}